// Definitions towards the midi standard held by the Midi Manufacturers Association
// Please refer to specification of the MMA at http://www.midid.org

// TODO Further implementation of the midi standard

using System;

namespace TagTool.Devices.Midi
{
    public static class MidiStandard
    {
        public const int NumberOfChannels = 16;
        public static uint GetMessageStatus(uint status)
        {
            return (status & (uint)MidiMessageMask.LowMask);
        }
    }

    /// <summary> Bitmask definition for midi messages </summary>
    public enum MidiMessageMask : uint
    {
        Data = 0x7F,     // first seven bits of data byte
        HighMask = 0x0F, // mask the upper four bits of the status byte
        LowMask = 0xF0   // mask the lower four bits of the status byte
    }

    /// <summary> Midi message states </summary>
    public enum MidiMessageStatus : uint
    {
        // Channel voice messages
        NoteOff = 0x80, // To indicate NoteOff, some devices send NoteOn with zero velocity
        NoteOn = 0x90,
        PolyphonicKeyPressure = 0xA0,
        ControlChange = 0xB0,
        ProgramChange = 0xC0,
        ChannelPressure = 0xD0,
        PitchWheelChange = 0xE0,
        // Channel mode messages
        ChannelModeControl = 0xB0,
        // System common messages
        SystemExclusive = 0xF0,
        /* Undefined 0xF1 reserved */
        SongPositionPointer = 0xF2,
        SongSelect = 0xF3,
        /* Undefined 0xF4 reserved */
        /* Undefined 0xF5 reserved */
        TuneRequest = 0xF6,
        EndExclusive = 0xF7,
        // System real-time messages, no need to evaluate data
        TimingClock = 0xF8,
        /* Undefined 0xF9 reserved */
        Start = 0xFA,
        Continue = 0xFB,
        Stop = 0xFC,
        /* Undefined 0xFD reserved */
        ActiveSensing = 0xFE,
        Reset = 0xFF
    }

    /// <summary> Definition of midi output technologies </summary>
    public enum MidiOutputTechnology
    {
        MidiPort = 1, // MIDI hardware port.
        Synthesizer = 2, //Synthesizer.
        SquareWaveSynthesizer = 4, //Square wave synthesizer.
        FMSynthesizer = 8, // FM synthesizer.
        Mapper = 16, //Microsoft MIDI mapper.
        WaveTable = 32, // Hardware wavetable synthesizer.
        SWSynthesizer = 64 //Software synthesizer.
    }

    /// <summary> Definition of midi controllers </summary>
    public enum MidiControllerType
    {
        BankSelectCoarse = 0,
        ModulationWheelCoarse = 1,
        BreathControllerCoarse = 2,
        FootPedalCoarse = 4,
        PortamentoTimeCoarse = 5,
        DataEntryCoarse = 6,
        VolumeCoarse = 7,
        BalanceCoarse = 8,
        PanPositionCoarse = 10,
        ExpressionCoarse = 11,
        EffectControlOneCoarse = 12,
        EffectControlTwoCoarse = 13,
        GeneralPurposeSliderOne = 16,
        GeneralPurposeSliderTwo = 17,
        GeneralPurposeSliderThree = 18,
        GeneralPurposeSliderFour = 19,
        BankSelectFine = 32,
        ModulationWheelFine = 33,
        BreathControllerFine = 34,
        FootPedalFine = 36,
        PortamentoTimeFine = 37,
        DataEntryFine = 38,
        VolumeFine = 39,
        BalanceFine = 40,
        PanPositionFine = 42,
        ExpressionFine = 43,
        EffectControlOneFine = 44,
        EffectControlTwoFine = 45,
        HoldPedal = 64, // (on/off)
        Portamento = 65, // (on/off)
        SustenutoPedal = 66, // (on/off)
        SoftPedal = 67, // (on/off)
        LegatoPedal = 68, // (on/off)
        HoldTwoPedal = 69, // (on/off)
        SoundVariation = 70,
        SoundTimbre = 71,
        SoundReleaseTime = 72,
        SoundAttackTime = 73,
        SoundBrightness = 74,
        SoundControlSix = 75,
        SoundControlSeven = 76,
        SoundControlEight = 77,
        SoundControlNine = 78,
        SoundControlTen = 79,
        GeneralPurposeButtonOne = 80, // (on/off)
        GeneralPurposeButtonTwo = 81, // (on/off)
        GeneralPurposeButtonThree = 82, // (on/off)
        GeneralPurposeButtonFour = 83, // (on/off)
        EffectsLevel = 91,
        TremuloLevel = 92,
        ChorusLevel = 93,
        CelesteLevel = 94,
        PhaserLevel = 95,
        DataButtonIncrement = 96,
        DataButtonDecrement = 97,
        NonRegisteredParameterOne = 98, // fine
        NonRegisteredParameterTwo = 99, // coarse
        RegisteredParameterOne = 100, // fine
        RegisteredParameterTwo = 101, // coarse
        AllSoundOff = 120,
        AllControllersOff = 121,
        LocalKeyboard = 122, //(on/off)
        AllNotesOff = 123,
        OmniModeOff = 124,
        OmniModeOn = 125,
        MonoOperation = 126,
        PolyOperation = 127
    }
}
